package com.czmh.etc.onlinepubsys.controller.mingchuang;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.czmh.etc.common.core.utils.Sequence;
import com.czmh.etc.onlinepubsys.configuration.WxAppletConfig;
import com.czmh.etc.onlinepubsys.dto.UserInfo;
import com.czmh.etc.onlinepubsys.entity.mingchuang.CurrentContext;
import com.czmh.etc.onlinepubsys.entity.mingchuang.Device;
import com.czmh.etc.onlinepubsys.entity.mingchuang.EtcOrder;
import com.czmh.etc.onlinepubsys.json.JsonResult;
import com.czmh.etc.onlinepubsys.json.mingchuang.JSONResult;
import com.czmh.etc.onlinepubsys.model.EtcDevice;
import com.czmh.etc.onlinepubsys.model.EtcObuDTO;
import com.czmh.etc.onlinepubsys.model.EtcPayOrder;
import com.czmh.etc.onlinepubsys.model.EtcUser;
import com.czmh.etc.onlinepubsys.request.mingchuang.EtcOrderStateRequest;
import com.czmh.etc.onlinepubsys.request.mingchuang.WechatNotifyRespone;
import com.czmh.etc.onlinepubsys.services.EtcOrderService;
import com.czmh.etc.onlinepubsys.services.EtcPayOrderService;
import com.czmh.etc.onlinepubsys.services.EtcUserInfoSevice;
import com.czmh.etc.onlinepubsys.services.mingchuang.*;
import com.czmh.etc.onlinepubsys.utils.JsonResultUtil;
import com.czmh.etc.onlinepubsys.utils.RedisUtil;
import com.czmh.etc.onlinepubsys.utils.WeiXinPayUtils;
import com.czmh.etc.onlinepubsys.utils.mingchuang.PayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/{version}/api/mingchang/order")
@Api(tags = "ETC订单接口【新】- 铭创")
public class EtcOrderController {
    @Value("${spring.profiles.active}")
    private String profile;

    @Autowired
    private WxAppletConfig config;

    @Autowired
    private IEtcOrderService etcOrderService;
    @Autowired
    private IWechatService wechatService;
    @Autowired
    private ICurrentContextService currentContextService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IExchangeCodeService exchangeCodeService;
    @Autowired
    private EtcOrderService etcOrderServicee;
    @Autowired
    private EtcUserInfoSevice etcUserInfoSevice;
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private EtcPayOrderService etcPayOrderService;

    @ApiOperation("更新订单状态")
    @PostMapping("/update")
    public JSONResult update(@RequestBody EtcOrder entity) {
        log.info("更新订单状态:{}", JSON.toJSONString(entity));
/*        // 手机号+验证码登录
        String redisValidCode = String.valueOf(redisUtil.get(entity.getPhone()));
        if (StringUtils.isNotEmpty(entity.getValidCode()) && StringUtils.isNotEmpty(redisValidCode)
                && (entity.getValidCode().equals(redisValidCode))) {
            if ((redisUtil.get("unCheckPhoneList") != null ? String.valueOf(redisUtil.get("unCheckPhoneList")) : "").indexOf(mobile) == -1) {
                // 注销验证码
                redisUtil.del(entity.getPhone());
            }
        } else {
            JSONResult result = new JSONResult();
            result.setCode(JSONResult.FAIL);
            result.setMessage("手机验证码不正确!");
            return result;
        }*/
        return etcOrderService.update(entity);
    }

    @PostMapping("/createOrderByCode")
    @ApiOperation("创建订单")
    public JSONResult createOrderByCode(@RequestBody EtcOrder entity) {
        log.info("使用兑换码创建订单:{}", JSON.toJSONString(entity));
        // 手机号+验证码登录
        String redisValidCode = String.valueOf(redisUtil.get(entity.getPhone()));
        if (StringUtils.isNotEmpty(entity.getValidCode()) && StringUtils.isNotEmpty(redisValidCode)
                && (entity.getValidCode().equals(redisValidCode))) {
            if ((redisUtil.get("unCheckPhoneList") != null ? String.valueOf(redisUtil.get("unCheckPhoneList")) : "").indexOf(entity.getPhone()) == -1) {
                // 注销验证码
                redisUtil.del(entity.getPhone());
            }
        } else {
            log.info("手机验证码不正确:{}", entity.getValidCode());
            JSONResult result = new JSONResult();
            result.setCode(JSONResult.FAIL);
            result.setMessage("手机验证码不正确！");
            return result;
        }




        JSONResult result = new JSONResult();

        //格式化兑换码
        if(entity.getCode() == null){
            result.setCode(JSONResult.FAIL);
            log.info("兑换码为空:{}", entity.getCode());
            result.setMessage("兑换码不能为空");
            return result;
        }else {
            entity.setCode(entity.getCode().trim());
        }

        String userId = entity.getUserId();

        CurrentContext ctx = currentContextService.getByUserId(userId);

        if (ctx != null) {
            result.setCode(JSONResult.FAIL);
            log.info("请先激活之前申请的设备:{}", ctx.getId());
            result.setMessage("请先激活之前申请的设备");
            return result;
        }

        Device device = deviceService.get(entity.getDvId());
        if (device == null) {
            JsonResult r = new JsonResult();
            JSONObject jsonObject = new JSONObject();
            int state = etcOrderServicee.isExistProductSn(entity.getDvId());
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("deleteFlag", "0");
            queryMap.put("productSn", entity.getDvId());
            EtcDevice etcDevice = etcOrderServicee.queryObject(queryMap);
            //判断产品编码对应的产品是否存在
            if (state == 0 || etcDevice == null) {
                result.setCode(JSONResult.FAIL);
                log.info("产品不存在:{}", entity.getDvId());
                result.setMessage("产品不存在");
                jsonObject.put("state", 0);
                jsonObject.put("etcDevice", null);
                result.setRspData(JSON.toJSONString(jsonObject));
                return result;
            } else {
                //产品存在需要判断产品是否被支付
                Integer count = etcOrderServicee.queryEtcPayState(entity.getDvId(), 1);
                if (count == null || count.intValue() == 0) {
                    //检查兑换码有效性
                    String code = entity.getCode();
                    if (!exchangeCodeService.checkExchangeCode(code, null)) {
                        result.setCode(JSONResult.FAIL);
                        log.info("该兑换码不可使用:{}", code);
                        result.setMessage("该兑换码不可使用！");
                        return result;
                    }

                    String orderNo = PayUtil.generateOrderNo();

                    entity.setOrderNo(orderNo);
                    entity.setAmount(etcDevice.getSaleMoney().multiply(new BigDecimal(100)).intValue());
                    entity.setBody(etcDevice.getProductSn());
                    entity.setPayType(1); //兑换码
                    entity.setPayNo(code);
                    entity.setPayState(1);

                    ctx = new CurrentContext();
                    ctx.setUserId(userId);
                    ctx.setOrderNo(entity.getOrderNo());
                    ctx.setState(1);
                    etcOrderService.saveOrderAndContext(entity, ctx, code);

                    //兑换码支付成功则更新手机号码到用户信息当中
                    EtcUser e = etcUserInfoSevice.queryUserInfo(entity.getUserId());
                    e.setUser_phone(entity.getPhone());
                    e.setUser_loginname(entity.getPhone());
                    etcUserInfoSevice.updateUser(e);
                    return result;
                } else {
                    result.setCode(JSONResult.FAIL);
                    log.info("产品不可用!:{}", entity.getDvId());
                    result.setMessage("产品不可用");
                    jsonObject.put("state", 2);
                    jsonObject.put("etcDevice", null);
                    result.setRspData(JSON.toJSONString(jsonObject));
                    return result;
                }
            }
        }
        //产品存在需要判断产品是否被支付
        Integer count = etcOrderServicee.queryEtcPayState(entity.getDvId(), 1);
        if (count != null && count.intValue() == 1) {
            JSONObject jsonObject = new JSONObject();
            result.setCode(JSONResult.FAIL);
            result.setMessage("产品不可用");
            log.info("产品不可用!!:{}", entity.getDvId());
            jsonObject.put("state", 2);
            return result;
        }
        //检查兑换码有效性
        String code = entity.getCode();
        if (!exchangeCodeService.checkExchangeCode(code, null)) {
            log.info("不支持兑换该产品:{}", code);
            result.setCode(JSONResult.FAIL);
            result.setMessage("不支持兑换该产品");
            return result;
        }

        String orderNo = PayUtil.generateOrderNo();

        entity.setOrderNo(orderNo);
        entity.setAmount(device.getAmount());
        entity.setBody(device.getName());
        entity.setPayType(1); //兑换码
        entity.setPayNo(code);
        entity.setPayState(1);

        ctx = new CurrentContext();
        ctx.setUserId(userId);
        ctx.setOrderNo(entity.getOrderNo());
        ctx.setState(1);
        etcOrderService.saveOrderAndContext(entity, ctx, code);

        //兑换码支付成功则更新手机号码到用户信息当中
        EtcUser e = etcUserInfoSevice.queryUserInfo(entity.getUserId());
        e.setUser_phone(entity.getPhone());
        e.setUser_loginname(entity.getPhone());
        etcUserInfoSevice.updateUser(e);

        return result;
    }

    @PostMapping("/createOrder")
    @ApiOperation("微信创建订单")
    public JSONResult createOrder(@RequestBody EtcOrder entity) {
        log.info("微信创建订单:{}", JSON.toJSONString(entity));
        //产品存在需要判断产品是否被支付
        Integer count = etcOrderServicee.queryEtcPayState(entity.getDvId(), 1);
        if (count != null && count.intValue() == 1) {
            JSONResult result = new JSONResult();
            JSONObject jsonObject = new JSONObject();
            result.setCode(JSONResult.FAIL);
            result.setMessage("产品不可用");
            jsonObject.put("state", 2);
            return result;
        }
        // 手机号+验证码登录
        String redisValidCode = String.valueOf(redisUtil.get(entity.getPhone()));
        if (StringUtils.isNotEmpty(entity.getValidCode()) && StringUtils.isNotEmpty(redisValidCode)
                && (entity.getValidCode().equals(redisValidCode))) {
            if ((redisUtil.get("unCheckPhoneList") != null ? String.valueOf(redisUtil.get("unCheckPhoneList")) : "").indexOf(entity.getPhone()) == -1) {
                // 注销验证码
                redisUtil.del(entity.getPhone());
            }
        } else {
            JSONResult result = new JSONResult();
            result.setCode(JSONResult.FAIL);
            result.setMessage("手机验证码不正确！");
            return result;
        }

        JSONResult result = new JSONResult();

        //如果用户存在且手机号码跟收货手机号码不同则根据收货手机号码创建新用户信息
        EtcUser e = etcUserInfoSevice.queryUserInfo(entity.getUserId());
        if(null == e){
            EtcUser user = new EtcUser();
            user.setUser_id(Sequence.getId());
            user.setCreate_time(new Date());
            user.setUpdate_time(new Date());
            user.setUser_sex(1);
            user.setUser_status(0);
            // 1.初始化ETC用户信息
            etcUserInfoSevice.insert(user);
        }else if(StringUtils.isNotEmpty(e.getUser_phone()) && !e.getUser_phone().equalsIgnoreCase(entity.getPhone())){
            result.setCode(JSONResult.FAIL);
            result.setMessage("该手机号码已经绑定其他ETC！");
            return result;
        }

        String userId = entity.getUserId();

        CurrentContext ctx = currentContextService.getByUserId(userId);

        if (ctx != null) {
            result.setCode(JSONResult.FAIL);
            result.setMessage("请先激活之前申请的设备");
            return result;
        }

        Device device = deviceService.get(entity.getDvId());
        //接入新库存需要判断库存逻辑
        if (device == null) {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("deleteFlag", "0");
            queryMap.put("productSn", entity.getDvId());
            EtcDevice etcDevice = etcOrderServicee.queryObject(queryMap);
            if (null != etcDevice){
                Device device1 = new Device();
                device1.setAmount(etcDevice.getSaleMoney().multiply(new BigDecimal(100)).intValue());
                device1.setName(etcDevice.getProductSn());
                device = device1;
            }
        }
        if (device == null) {
            result.setCode(JSONResult.FAIL);
            result.setMessage("请正确选择你要的设备");
            return result;
        }

        String orderNo = PayUtil.generateOrderNo();

        String body = device.getName();
        Integer amount = device.getAmount();

        if ("dev".equals(profile) || "test".equals(profile)) { //测试环境付款1分钱
            amount = 1;
        }
        //调用微信支付下单
        log.info("微信支付下单,订单号:{},设备价格:{}", orderNo, amount);

        result = wechatService.unifiedOrder(entity.getOpenId(), orderNo, body, amount);

        if (JSONResult.SUCCESS.equals(result.getCode())) {
            log.info("保存订单:{}", orderNo);
            //记录当前进行时信息
            int payState = 0; //默认是未付款

            entity.setPayType(0); //微信支付
            entity.setOrderNo(orderNo);
            entity.setAmount(amount);
            entity.setPayState(payState);
            entity.setBody(body);

            ctx = new CurrentContext();
            ctx.setUserId(userId);
            ctx.setOrderNo(entity.getOrderNo());
            ctx.setState(payState);
            etcOrderService.saveOrderAndContext(entity, ctx, null);
        }
        return result;
    }

    /**
     * 微信支付回调方法
     * @param req
     * @return
     */
    @PostMapping(value = "/notify", produces = "text/xml;charset=UTF-8")
    public String notify(HttpServletRequest req) throws Exception {
        Document doc = DocumentHelper.createDocument();
        Element root = doc.addElement("xml");

        SortedMap<String, String> map = WeiXinPayUtils.parseXml(req.getInputStream());
        log.info("微信支付回调:{}", map);
        if (!wechatService.checkSign(map)) {
            root.addElement("return_code").addText("FAIL");
            root.addElement("return_msg").addText("验证签名失败");
            return doc.asXML();
        }

        WechatNotifyRespone resp = new WechatNotifyRespone();
        BeanUtils.copyProperties(resp, map);

        if (resp.getReturn_code().equals("SUCCESS") && resp.getResult_code().equals("SUCCESS")) {
            String out_trade_no = resp.getOut_trade_no();
            log.info("微信支付验签成功,更新订单:{}", out_trade_no);

            etcOrderService.updateByOrderNo(out_trade_no, resp.getTransaction_id(), 1);
            root.addElement("return_code").addText("SUCCESS");
            root.addElement("return_msg").addText("OK");

            //更新进行状态
            CurrentContext ctx = currentContextService.getByOrderNo(out_trade_no);
            if(ctx.getPayMode() == 0){
                ctx.setState(1); //已付款
                currentContextService.update(ctx);
            }

            //把订单对应的手机号码更新到用户信息当中
            EtcOrder etcOrder = etcOrderService.getByOrderNo(out_trade_no);
            EtcUser etcUser = etcUserInfoSevice.queryUserInfo(etcOrder.getUserId());
            if(etcUser != null){
                //if(etcUser != null && StringUtils.isNotEmpty(etcOrder.getPhone())){
                etcUser.setUser_phone(etcOrder.getPhone());
                etcUser.setUser_loginname(etcOrder.getPhone());
                etcUserInfoSevice.updateUser(etcUser);
            }
        } else {
            root.addElement("return_code").addText("FAIL");
            root.addElement("return_msg").addText("支付失败");
        }
        return doc.asXML();
    }

    @PostMapping("/getPayState")
    @ApiOperation("查询支付状态")
    public JSONResult getPayState(@RequestBody EtcOrderStateRequest req) {
        log.info("查询支付状态:{}", JSON.toJSONString(req));
        CurrentContext ctx = currentContextService.getByUserId(req.getUserId());
        return wechatService.getPayState(ctx.getOrderNo());
    }
}
